Programming to an Interface
Programming to an interface means writing client code against a stable abstraction rather than a specific implementation. The consumer knows what operations are guaranteed but does not depend on how those operations are implemented. This improves substitutability, reduces coupling and allows implementations to evolve independently. It does not mean every class needs an interface; the abstraction should provide real value at a dependency or variability boundary.
Depend on behavior/contracts rather than concrete implementation details.
Supports implementation substitution.
Improves testability.
Reduces coupling between modules.
Supports dependency inversion.
Avoid creating interfaces purely for every class without a meaningful abstraction boundary.